1 module mpdec.deimos;
2 
3 import std.stdio;
4 import core.stdc.stdint;
5 import core.stdc.stdlib;
6 
7 // This a D translation of the original C header for libmpdec (mpdecimal.h)
8 // following the guidelines at https://dlang.org/spec/interfaceToC.html 
9 // written by Pablo De Nápoli.
10 
11 // The copyright notice of the original sotware is the following:
12 
13 /*
14  * Copyright (c) 2008-2016 Stefan Krah. All rights reserved.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  *
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  *
23  * 2. Redistributions in binary form must reproduce the above copyright
24  *    notice, this list of conditions and the following disclaimer in the
25  *    documentation and/or other materials provided with the distribution.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  */
39 
40 // (this modified version is distributed under the same conditions).
41 
42 extern (C)
43 {
44 	char *mpd_version();
45 
46 /******************************************************************************/
47 /*                              Configuration                                 */
48 /******************************************************************************/
49 
50 // We use the 64 bit version
51 
52 	/* types for modular and base arithmetic */
53 
54 	const MPD_UINT_MAX = UINT64_MAX;
55 	const MPD_BITS_PER_UINT = 64;
56 	alias mpd_uint_t=uint64_t ;  /* unsigned mod type */
57 
58 	const MPD_SIZE_MAX=SIZE_MAX;
59 	alias mpd_size_t=size_t ; /* unsigned size type */
60 
61 	/* type for exp, digits, len, prec */
62 	const MPD_SSIZE_MAX=INT64_MAX;
63 	const MPD_SSIZE_MIN=INT64_MIN;
64 	alias mpd_ssize_t=int64_t;
65 	alias _mpd_strtossize=strtoll;
66 
67 
68 /* decimal arithmetic */
69 enum MPD_RADIX =10000000000000000000UL;  /* 10**19 */
70 enum MPD_RDIGITS= 19;
71 enum MPD_MAX_POW10=19;
72 enum MPD_EXPDIGITS=19;  /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */
73 
74 enum MPD_MAXTRANSFORM_2N=4294967296;      /* 2**32 */
75 enum MPD_MAX_PREC=999999999999999999;
76 enum MPD_MAX_PREC_LOG2=64;
77 enum MPD_ELIMIT=1000000000000000000;
78 enum MPD_MAX_EMAX=999999999999999999;    /* ELIMIT-1 */
79 enum MPD_MIN_EMIN=(-999999999999999999);  /* -EMAX */
80 enum MPD_MIN_ETINY=(MPD_MIN_EMIN-(MPD_MAX_PREC-1));
81 enum MPD_EXP_INF=2000000000000000001;
82 enum MPD_EXP_CLAMP=(-4000000000000000001);
83 enum MPD_MAXIMPORT=105263157894736842L; /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
84 
85 /******************************************************************************/
86 /*                                Context                                     */
87 /******************************************************************************/
88 
89 enum {
90     MPD_ROUND_UP,          /* round away from 0               */
91     MPD_ROUND_DOWN,        /* round toward 0 (truncate)       */
92     MPD_ROUND_CEILING,     /* round toward +infinity          */
93     MPD_ROUND_FLOOR,       /* round toward -infinity          */
94     MPD_ROUND_HALF_UP,     /* 0.5 is rounded up               */
95     MPD_ROUND_HALF_DOWN,   /* 0.5 is rounded down             */
96     MPD_ROUND_HALF_EVEN,   /* 0.5 is rounded to even          */
97     MPD_ROUND_05UP,        /* round zero or five away from 0  */
98     MPD_ROUND_TRUNC,       /* truncate, but set infinity      */
99     MPD_ROUND_GUARD
100 };
101 
102 enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD };
103 
104 extern const char *[MPD_ROUND_GUARD]mpd_round_string;
105 extern const char *[MPD_CLAMP_GUARD]mpd_clamp_string;
106 
107 	struct mpd_context_t {
108     mpd_ssize_t prec;   /* precision */
109     mpd_ssize_t emax;   /* max positive exp */
110     mpd_ssize_t emin;   /* min negative exp */
111     uint32_t traps;     /* status events that should be trapped */
112     uint32_t status;    /* status flags */
113     uint32_t newtrap;   /* set by mpd_addstatus_raise() */
114     int      round;     /* rounding mode */
115     int      clamp;     /* clamp mode */
116     int      allcr;     /* all functions correctly rounded */
117 	} ;
118 
119 	void mpd_dflt_traphandler(mpd_context_t *);
120 
121 void mpd_setminalloc(mpd_ssize_t n);
122 void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec);
123 
124 void mpd_maxcontext(mpd_context_t *ctx);
125 void mpd_defaultcontext(mpd_context_t *ctx);
126 void mpd_basiccontext(mpd_context_t *ctx);
127 int mpd_ieee_context(mpd_context_t *ctx, int bits);
128 
129 mpd_ssize_t mpd_getprec(const mpd_context_t *ctx);
130 mpd_ssize_t mpd_getemax(const mpd_context_t *ctx);
131 mpd_ssize_t mpd_getemin(const mpd_context_t *ctx);
132 int mpd_getround(const mpd_context_t *ctx);
133 uint32_t mpd_gettraps(const mpd_context_t *ctx);
134 uint32_t mpd_getstatus(const mpd_context_t *ctx);
135 int mpd_getclamp(const mpd_context_t *ctx);
136 int mpd_getcr(const mpd_context_t *ctx);
137 
138 int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec);
139 int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax);
140 int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin);
141 int mpd_qsetround(mpd_context_t *ctx, int newround);
142 int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags);
143 int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags);
144 int mpd_qsetclamp(mpd_context_t *ctx, int c);
145 int mpd_qsetcr(mpd_context_t *ctx, int c);
146 void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
147 
148 
149 /******************************************************************************/
150 /*                           Decimal Arithmetic                               */
151 /******************************************************************************/
152 
153 
154 /* mpd_t flags */
155 const MPD_POS=                 	cast(uint8_t)0;
156 const MPD_NEG=                	cast(uint8_t)1;
157 const MPD_INF=                 	cast(uint8_t)2;
158 const MPD_NAN=                  cast(uint8_t)4;
159 const MPD_SNAN=                 cast(uint8_t)8;
160 const MPD_SPECIAL=  (MPD_INF|MPD_NAN|MPD_SNAN);
161 const MPD_STATIC=              	cast(uint8_t)16;
162 const MPD_STATIC_DATA=         	cast(uint8_t)32;
163 const MPD_SHARED_DATA=          cast(uint8_t)64;
164 const MPD_CONST_DATA=           cast(uint8_t)128;
165 const MPD_DATAFLAGS=  (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA);
166 
167 
168 /* mpd_t */
169 struct mpd_t {
170     uint8_t flags;
171     mpd_ssize_t exp;
172     mpd_ssize_t digits;
173     mpd_ssize_t len;
174     mpd_ssize_t alloc;
175     mpd_uint_t *data;
176 };
177 
178 alias uchar = char; /* chars are unsigned in D */
179 
180 
181 /******************************************************************************/
182 /*                       Quiet, thread-safe functions                         */
183 /******************************************************************************/
184 
185 /* format specification */
186 struct mpd_spec_t {
187     mpd_ssize_t min_width; /* minimum field width */
188     mpd_ssize_t prec;      /* fraction digits or significant digits */
189     char type;             /* conversion specifier */
190     char alignment;        /* alignment : the original name was align but it is a reserved keyword in D */
191     char sign;             /* sign printing/alignment */
192     char[5] fill;          /* fill character */
193     const char *dot;       /* decimal point */
194     const char *sep;       /* thousands separator */
195     const char *grouping;  /* grouping of digits */
196 };
197 
198 /* output to a string */
199 char *mpd_to_sci(const mpd_t *dec, int fmt);
200 char *mpd_to_eng(const mpd_t *dec, int fmt);
201 mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt);
202 mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt);
203 int mpd_validate_lconv(mpd_spec_t *spec);
204 int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps);
205 char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status);
206 char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status);
207 
208 const MPD_NUM_FLAGS=15;
209 const MPD_MAX_FLAG_STRING=208;
210 const MPD_MAX_FLAG_LIST = MPD_MAX_FLAG_STRING+18;
211 const MPD_MAX_SIGNAL_LIST=12;
212 int mpd_snprint_flags(char *dest, int nmemb, uint32_t flags);
213 int mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char*[] flag_string);
214 int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char*[] flag_string);
215 
216 /* output to a file */
217 void mpd_fprint(FILE *file, const mpd_t *dec);
218 void mpd_print(const mpd_t *dec);
219 
220 /* assignment from a string */
221 void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status);
222 
223 /* set to NaN with error flags */
224 void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status);
225 /* set a special with sign and type */
226 void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type);
227 /* set coefficient to zero or all nines */
228 void mpd_zerocoeff(mpd_t *result);
229 void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
230 
231 /* quietly assign a C integer type to an mpd_t */
232 void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
233 void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
234 void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
235 void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
236 void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
237 void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
238 
239 /* quietly assign a C integer type to an mpd_t with a static coefficient */
240 void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
241 void mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
242 void mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
243 void mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
244 
245 /* quietly get a C integer type from an mpd_t */
246 mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
247 mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
248 mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
249 
250 int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
251 uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
252 int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
253 uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
254 
255 /* quiet functions */
256 int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
257 int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
258 void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
259 
260 char *mpd_class(const mpd_t *a, const mpd_context_t *ctx);
261 
262 int mpd_qcopy(mpd_t *result, const mpd_t *a,  uint32_t *status);
263 mpd_t *mpd_qncopy(const mpd_t *a);
264 int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status);
265 int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status);
266 int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status);
267 
268 void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
269 void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
270 void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
271 void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
272 void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
273 void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
274 int mpd_same_quantum(const mpd_t *a, const mpd_t *b);
275 
276 void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
277 int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
278 mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
279 mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n);
280 void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
281 void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, uint32_t *status);
282 
283 int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status);
284 int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
285 int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
286 int mpd_cmp_total(const mpd_t *a, const mpd_t *b);
287 int mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b);
288 int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b);
289 int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b);
290 
291 void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
292 void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
293 void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
294 void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
295 void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
296 
297 void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
298 void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
299 void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
300 void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
301 void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
302 void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
303 void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
304 void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
305 void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
306 void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
307 void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
308 void mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
309 void mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
310 void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
311 void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
312 void mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
313 void mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
314 void mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
315 void mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
316 void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
317 void mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
318 void mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
319 void mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
320 void mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
321 void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
322 void mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
323 void mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
324 void mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
325 void mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
326 void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status);
327 void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
328 void mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
329 void mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
330 void mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
331 void mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
332 void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
333 void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
334 void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
335 void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
336 void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status);
337 void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status);
338 void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
339 void mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status);
340 void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
341 void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
342 void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
343 void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
344 
345 void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
346 void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
347 void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
348 void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
349 void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
350 void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
351 void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
352 void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
353 
354 size_t mpd_sizeinbase(const mpd_t *a, uint32_t base);
355 void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
356                      uint8_t srcsign, uint32_t srcbase,
357                      const mpd_context_t *ctx, uint32_t *status);
358 void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen,
359                      uint8_t srcsign, uint32_t srcbase,
360                      const mpd_context_t *ctx, uint32_t *status);
361 size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base,
362                        const mpd_t *src, uint32_t *status);
363 size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base,
364                        const mpd_t *src, uint32_t *status);
365 
366 
367 /******************************************************************************/
368 /*                           Signalling functions                             */
369 /******************************************************************************/
370 
371 
372 char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx);
373 void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
374 void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
375 size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
376 size_t mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
377 void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
378 int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
379 int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
380 void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx);
381 void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx);
382 void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
383 void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
384 void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
385 void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
386 void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
387 void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
388 void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
389 void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
390 void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
391 void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
392 
393 mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
394 mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
395 mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
396 int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx);
397 uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx);
398 int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
399 uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
400 void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
401 void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
402 void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
403 void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
404 void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
405 void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
406 void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
407 void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
408 void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
409 void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
410 void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
411 void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
412 mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
413 void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
414 void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
415 void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
416 void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
417 int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
418 int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
419 int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
420 void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
421 void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
422 void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
423 void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
424 void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
425 void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
426 void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
427 void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
428 void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
429 void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
430 void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
431 void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
432 void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
433 void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
434 void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
435 void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
436 void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
437 void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
438 void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx);
439 void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
440 void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
441 void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
442 void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
443 void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
444 void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
445 void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
446 void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
447 void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
448 void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
449 void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
450 void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
451 void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
452 void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
453 void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
454 void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
455 void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx);
456 void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx);
457 void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
458 void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx);
459 void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
460 void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
461 void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
462 void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
463 void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
464 void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
465 void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
466 void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
467 void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
468 void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
469 
470 void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
471 void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
472 void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
473 void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
474 void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
475 void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
476 void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
477 void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
478 
479 
480 /******************************************************************************/
481 /*                       Get attributes of a decimal                          */
482 /******************************************************************************/
483 
484 mpd_ssize_t mpd_adjexp(const mpd_t *dec);
485 mpd_ssize_t mpd_etiny(const mpd_context_t *ctx);
486 mpd_ssize_t mpd_etop(const mpd_context_t *ctx);
487 mpd_uint_t mpd_msword(const mpd_t *dec);
488 int mpd_word_digits(mpd_uint_t word);
489 /* most significant digit of a word */
490 mpd_uint_t mpd_msd(mpd_uint_t word);
491 /* least significant digit of a word */
492 mpd_uint_t mpd_lsd(mpd_uint_t word);
493 /* coefficient size needed to store 'digits' */
494 mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits);
495 /* number of digits in the exponent, undefined for MPD_SSIZE_MIN */
496 int mpd_exp_digits(mpd_ssize_t exp);
497 int mpd_iscanonical(const mpd_t *dec);
498 int mpd_isfinite(const mpd_t *dec);
499 int mpd_isinfinite(const mpd_t *dec);
500 int mpd_isinteger(const mpd_t *dec);
501 int mpd_isnan(const mpd_t *dec);
502 int mpd_isnegative(const mpd_t *dec);
503 int mpd_ispositive(const mpd_t *dec);
504 int mpd_isqnan(const mpd_t *dec);
505 int mpd_issigned(const mpd_t *dec);
506 int mpd_issnan(const mpd_t *dec);
507 int mpd_isspecial(const mpd_t *dec);
508 int mpd_iszero(const mpd_t *dec);
509 /* undefined for special numbers */
510 int mpd_iszerocoeff(const mpd_t *dec);
511 int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx);
512 int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx);
513 /* odd word */
514 int mpd_isoddword(mpd_uint_t word);
515 /* odd coefficient */
516 int mpd_isoddcoeff(const mpd_t *dec);
517 /* odd decimal, only defined for integers */
518 int mpd_isodd(const mpd_t *dec);
519 /* even decimal, only defined for integers */
520 int mpd_iseven(const mpd_t *dec);
521 /* 0 if dec is positive, 1 if dec is negative */
522 uint8_t mpd_sign(const mpd_t *dec);
523 /* 1 if dec is positive, -1 if dec is negative */
524 int mpd_arith_sign(const mpd_t *dec);
525 long mpd_radix();
526 int mpd_isdynamic(const mpd_t *dec);
527 int mpd_isstatic(const mpd_t *dec);
528 int mpd_isdynamic_data(const mpd_t *dec);
529 int mpd_isstatic_data(const mpd_t *dec);
530 int mpd_isshared_data(const mpd_t *dec);
531 int mpd_isconst_data(const mpd_t *dec);
532 mpd_ssize_t mpd_trail_zeros(const mpd_t *dec);
533 
534 
535 /******************************************************************************/
536 /*                       Set attributes of a decimal                          */
537 /******************************************************************************/
538 
539 /* set number of decimal digits in the coefficient */
540 void mpd_setdigits(mpd_t *result);
541 void mpd_set_sign(mpd_t *result, uint8_t sign);
542 /* copy sign from another decimal */
543 void mpd_signcpy(mpd_t *result, const mpd_t *a);
544 void mpd_set_infinity(mpd_t *result);
545 void mpd_set_qnan(mpd_t *result);
546 void mpd_set_snan(mpd_t *result);
547 void mpd_set_negative(mpd_t *result);
548 void mpd_set_positive(mpd_t *result);
549 void mpd_set_dynamic(mpd_t *result);
550 void mpd_set_static(mpd_t *result);
551 void mpd_set_dynamic_data(mpd_t *result);
552 void mpd_set_static_data(mpd_t *result);
553 void mpd_set_shared_data(mpd_t *result);
554 void mpd_set_const_data(mpd_t *result);
555 void mpd_clear_flags(mpd_t *result);
556 void mpd_set_flags(mpd_t *result, uint8_t flags);
557 void mpd_copy_flags(mpd_t *result, const mpd_t *a);
558 
559 
560 /******************************************************************************/
561 /*                            Memory handling                                 */
562 /******************************************************************************/
563 
564 extern (C) void* function(size_t size) mpd_mallocfunc;
565 extern (C) void* function(size_t nmemb, size_t size) mpd_callocfunc;
566 extern (C) void* function(void* ptr, size_t size) mpd_reallocfunc;
567 extern (C) void function(void* ptr) mpd_free;
568 
569 void *mpd_callocfunc_em(size_t nmemb, size_t size);
570 
571 void *mpd_alloc(mpd_size_t nmemb, mpd_size_t size);
572 void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size);
573 void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
574 void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
575 
576 mpd_t *mpd_qnew();
577 mpd_t *mpd_new(mpd_context_t *ctx);
578 mpd_t *mpd_qnew_size(mpd_ssize_t size);
579 void mpd_del(mpd_t *dec);
580 
581 void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len);
582 int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status);
583 int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
584 void mpd_minalloc(mpd_t *result);
585 
586 int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
587 int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
588 
589 
590 }
591